package com.piece.core.log.support.socket;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantLock;

public class LoggerQueue {

    // 队列大小
    public static final int QUEUE_MAX_SIZE = 1000;

    // 阻塞队列
    private BlockingQueue blockingQueue = new LinkedBlockingQueue<>(QUEUE_MAX_SIZE);

    // 读取日志状态
    private AtomicBoolean read = new AtomicBoolean(false);

    private static LoggerQueue instance;

    private static ReentrantLock lock = new ReentrantLock();

    public static LoggerQueue getInstance() {
        if (null == instance) {
            lock.lock();
            if (null == instance) {
                instance = new LoggerQueue();
            }
            lock.unlock();
        }
        return instance;
    }

    /**
     * 消息入队
     */
    public boolean push(LoggerMessage log) {
        if (this.read.get()) {
            boolean result = false;
            try {
                result = this.blockingQueue.offer(log, 1000, TimeUnit.MILLISECONDS);
            } catch (InterruptedException e) {
                result = false;
            }
            if (!result && !this.read.get()) {
                // 非读取状态
                poll();
                return push(log);
            }
            return result;
        }

        return true;
    }

    /**
     * 消息出队
     */
    public LoggerMessage poll() {
        LoggerMessage result = null;
        try {
            result = (LoggerMessage) this.blockingQueue.poll(1000, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            result = null;
        }
        return result;
    }

    public void read() {
        this.read.getAndSet(true);
    }

    public void unRead() {
        this.read.getAndSet(false);
    }
}